TextMesh Proのエッジケース現象まとめ
概要
さわれば触るほど楽しいケースが出てくる。UUebViewでもしこたま遭遇していたが、LayouTaroを作っているとさらに出会う。
次のようなファンキーを発見した。多分以前のメモとかには出てこない。
・TMProはwhitespaceが特定の位置に来るとファンキーなことをする
・TMProが改行する位置をミスる
TMProはwhitespaceが特定の位置に来るとファンキーなことをする
whitespace、つまりスペースを含んだテキストとかを食わせると、まあ、表示幅とテキストの長さによっては、スペースが行の末尾に来ることがあるだろう。
例えば次のようなテキストがあるとする。[あ]、[い] の間には5つのスペースが入っている。
あ い
これを、例えば [あ] と [い] の間で改行が入るような幅に表示しようとするとしよう。
[あ]の後ろ、3つめのスペースを詰めたところでちょうど改行が起きるような幅を想定する。
あ // 3つめのスペースで改行が発生するような幅
い// 2つのスペースのあとに[い]が来る
こうなってくれるのがまあ、予想としては正しいと思うんだよね。
そしてここでもう一つ、理想としては、レイアウトする枠に対して、レイアウトされる文字は枠幅よりイコールかちょっと少ない位置で折り返しが発生する。
具体的には、1行目のコンテンツの返す幅は、
↓ この位置を表す幅 = あ + スペース + スペース + スペース の幅を合計した値で、これは枠幅より小さいはずだよな。
あ // 3つめのスペースで改行が発生するような幅
い// 2つのスペースのあとに[い]が来る
[あ]と[スペース]の幅をそれぞれ100pxだと仮定しよう。つまり1行目の幅は400あるはずなんだ。
でも違うんだ。実際はこうなるんだ。
あ // 3つめのスペースで改行が発生するような幅
い// 前の2つのスペースが消える
!?
やったぜ!!、[い]の前の2つのスペースが消えたね! なんで?
そして1行目の幅は? 幅はどうなんだ、教えてくれセフィロス。
↓ この位置を表す幅 = [あ] 単独の幅、、
あ // 3つめのスペースで改行が発生するような幅
い// 前の2つのスペースが消える
100を返してくる。 ふーん、 400じゃないんだ、、なんで、、?
カラクリはこうだ。
1. TMProは文章の末尾に来るスペースの存在自体をなかったことにするが、消す前にきちんと幅を測って改行だけはさせてくれる
2. TMProは文章の末尾に来るスペースを消すので、行に入るテキストの幅は、「スタート」から「最後に現れるスペース以外の文字」の幅になる
1.によって、2行目に来るはずの2つのスペースが消され、それでも改行だけはできて、
2.によって誤った幅情報が得られる。
これらを回避すると、スペースがロストインスペースしないで済み、正確な幅情報が得られる。
TMProが改行する位置をミスる
これには本当に参った。
レイアウトする枠の長さを1000pxとしよう。
カーニングの組み合わせ込みで幅100pxの文字なら、10個置くとちょうど枠を満たす。
↓ここがちょうど、枠のサイズと重なる
ああああああああああ
このパターンだと、例えば11文字目に何か文字がくれば、その文字は改行された先に送り出される。
11文字目に[い]が来るとしたら、
ああああああああああ
い
こうなると思うんだよね。
だがここで、[あ]が、もし、101pxの幅を持つとしたら?
誇張してちょっと大きなフォントでやったとしよう。同じフォントでも幅は変わる。
10個並べたら1010pxになるから、10個めの[あ]は2行目に行くはずだよね。
↓枠幅がここ。 9個目の[あ]と枠幅の隙間に最後の[あ]は入らないよなあ。
ああああああああああ//x 明確に入らないよね。
あい
ところが。こうならない組み合わせがある。
レイアウトした文字が枠のサイズを超えるんだ。
具体的にいうと、次のようにレイアウトされる。
↓枠幅がここ。
ああああああああああ//枠幅をワイルドに超えてくるんだが?
い
枠のサイズを与えてさーレイアウトをお願いしてるのにさー、枠のサイズを超えてレイアウトされるんだよ。怖い。
これはTMPro内での計算が1pxくらいの誤差を含むから起きる現象で、事前の回避策はない。
ふとレイアウトしてみて、レイアウト結果が枠の幅を超えていることがあって、それで発覚した。
ひどい時は大変ブレイブな感じで枠外にレイアウトが飛び出す。1文字だけだけどさー、与えた枠は守って欲しいんだよなー。
ほとんど全てのケースで枠内に収まるが、TMPro内の計算結果というブラックボックス性のせいで、レイアウトするまで観測できない。
なので、レイアウト後に恐る恐る計測して、枠を超えていたら、なんとかしよう。
ところで
ここで紹介した2つの問題が合成して発生することがあって、
・TMProが改行位置をミスり
・なおかつ1行目の末尾がスペースだと、
なんと、飛び出す上に正しい幅が計測できないんだよなあ! これには参ったよ。
一個ずつ仕留めれば倒せる。どんな生物でも170°のガーリック油で煮れば死ぬ。wikiで見た。あーーー茹でガニくいてー。
よいTMPro生活を! よいライブラリなので。